package pe.com.nextel.rms;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import javax.microedition.rms.RecordStoreNotOpenException;
import pe.com.nextel.util.ArrayList;
import pe.com.nextel.util.List;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStoreFullException;
import pe.com.nextel.util.Iterator;

/**
 * Clase para administrar la creacion de indices
 * @author eespinoza
 * @version 1.0 30/11/07
 */
public class RMSIndice extends GestorRMS {

    public RMSIndice(String nombre) {
        super(nombre);
    }

    public void abrirIndice() throws RecordStoreException {
        abrirRS();
    }

    /**
     *
     * @param arrByte
     * @throws java.io.IOException
     * @throws javax.microedition.rms.RecordStoreFullException
     * @throws javax.microedition.rms.RecordStoreException
     */
    public synchronized int guardarIndice(byte[] arrByte) throws IOException, RecordStoreFullException, RecordStoreException {
        return guardar(arrByte);

    }

    public synchronized int guardarIndice(String object) throws IOException, RecordStoreFullException, RecordStoreException {

        byte[] byteValor = object.getBytes();
        return guardar(byteValor);

    }

    public int guardarIndiceLista(List lista) throws IOException, RecordStoreFullException, RecordStoreException {

        ByteArrayOutputStream output = null;
        DataOutputStream dataOutput = null;
        try {
            output = new ByteArrayOutputStream();
            dataOutput = new DataOutputStream(output);

            dataOutput.writeInt(lista.size());
            for (Iterator it = lista.iterator(); it.hasNext();) {
                Integer integer = (Integer) it.next();
                dataOutput.write(integer.intValue());
            }

            return guardar(output.toByteArray());

        } finally {
            try {
                if (dataOutput != null) {
                    dataOutput.flush();
                    dataOutput.close();
                    dataOutput = null;
                }
                if (output != null) {
                    output.flush();
                    output.close();
                    output = null;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    public List getListaIndice() throws Exception {
        ByteArrayInputStream byteInputStream = null;
        DataInputStream dataInputStream = null;
        List lst = new ArrayList();

        if (getNumRecords() <= 0) {
            return lst;
        }

        try {

            byteInputStream = new ByteArrayInputStream(getRecord(1));
            dataInputStream = new DataInputStream(byteInputStream);
            //return recuperar(dataInputStream);
            int cant = dataInputStream.readInt();

            for (int i = 0; i < cant; i++) {

                lst.add(new Integer(dataInputStream.readInt()));

            }

            return lst;

        } finally {
            try {
                if (byteInputStream != null) {
                    byteInputStream.close();
                    byteInputStream = null;
                }
                if (dataInputStream != null) {
                    dataInputStream.close();
                    dataInputStream = null;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    public void actualizarIndiceLista(int codigo) throws Exception {

        // obtenemos los indices
        List listaTemp = getListaIndice();

        boolean flag = false;
        for (Iterator it = listaTemp.iterator(); it.hasNext();) {
            Integer valor = (Integer) it.next();
            if (valor.intValue() == codigo) {
                flag = true;
            }
        }
        // si no se encontro actualizar
        if (!flag) {
            listaTemp.add(new Integer(codigo));
            guardarIndiceLista(listaTemp);
        }
    }

    public void cerrarIndice() throws RecordStoreNotOpenException, RecordStoreException {
        cerrarRS();
    }
    /*   public synchronized void guardar(Object object) throws Exception{
    String strValor = (String)object;
    byte[] byteValor = strValor.getBytes();
    rs.addRecord(byteValor, 0, byteValor.length);
    }
     */
    /* public synchronized void borrarRecord(int recordId) throws Exception{
    rs.deleteRecord(recordId);
    }*/

    //Devuelve el RECORDID del Indice en un INTEGER
    public Integer getIndice(Integer codigo) throws Exception {

        RecordEnumeration registros = enumerateRecords(null, null, false);

        byte[] indByte;

        Integer intCodigo;

        Integer indice = null;

        int indx;

        while (registros.hasNextElement()) {

            indx = registros.nextRecordId();

            indByte = getRecord(indx);

            intCodigo = Integer.valueOf(new String(indByte));

            if (codigo.longValue() <= intCodigo.longValue()) {

                indice = new Integer(indx);
                break;
            }

        }

        registros.destroy();

        registros = null;

        return indice;

    }

     

    public int getIndiceOrdenadoString(String codigo) throws Exception {

         ByteArrayInputStream byteInputStream = null;
        DataInputStreamX dataInputStream = null;
        //RecordEnumeration registros = enumerateRecords(null, null, false);
        int pos = 0;
        try {

            byte[] indByte;
            String strCodigo;
            int tamanio = getNumRecords();
            //System.out.println("tamanio=" + tamanio);

            int inicio = 1;
            int fin = tamanio;
            int i = 0;
            boolean flag = false;
 

            while (inicio <= fin) {
                pos = (inicio + fin) / 2;
                //System.out.println("pos=" + pos);
                indByte = getRecord(pos);

                byteInputStream = new ByteArrayInputStream(indByte);
                dataInputStream = new DataInputStreamX(byteInputStream);

                strCodigo = dataInputStream.readString();

//                System.out.println("codigoCliente == strCodigo " + codigo + "|" + strCodigo + "|");

                if (codigo.compareTo(strCodigo)==0) {
                    flag = true;
                    break;
                } else if (codigo.compareTo(strCodigo) > 0) { //es menor

                    inicio = pos + 1;
                } else if (codigo.compareTo(strCodigo) < 0) { // es mayor

                    fin = pos - 1;
                }

                if (byteInputStream != null) {
                    byteInputStream.close();
                    byteInputStream = null;
                }
                if (dataInputStream != null) {
                    dataInputStream.close();
                    dataInputStream = null;
                }
            }

            //si no lo encuentra
            if (!flag) {
                pos = 0;
            }
        } finally {

            if (byteInputStream != null) {
                byteInputStream.close();
                byteInputStream = null;
            }
            if (dataInputStream != null) {
                dataInputStream.close();
                dataInputStream = null;
            }

        }
        return pos;
    }

    //Devuelve el RECORDID del Indice en un INTEGER
    public int getIndice(String codigo) throws Exception {
        RecordEnumeration registros = enumerateRecords(null, null, false);
        try {
            byte[] indByte;
            String strCodigo;

            while (registros.hasNextElement()) {
                int indx = registros.nextRecordId();
                indByte = getRecord(indx);

                strCodigo = new String(indByte);
 
                if (codigo.equals(strCodigo)) {
                    return indx;
                }
            }
        } finally {

            if (registros != null) {
                registros.destroy();
                registros = null;
            }
        }
        return 0;
    }

    //Devuelve el RECORDID del Indice en un INTEGER
    public Integer getIndiceIgual(Integer codigo) throws Exception {
        RecordEnumeration registros = enumerateRecords(null, null, false);
        byte[] indByte;
        Integer intCodigo;
        Integer indice = null;
        int indx;
        while (registros.hasNextElement()) {
            indx = registros.nextRecordId();
            indByte = getRecord(indx);
            intCodigo = Integer.valueOf(new String(indByte));
            if (codigo.longValue() == intCodigo.longValue()) {
                indice = new Integer(indx);
                break;
            }
        }
        registros.destroy();
        registros = null;
        return indice;
    }

    //Devuelve un List con los RECORDID del Indice en un INTEGER
    public List getIndiceMultiple(Integer codigo) throws Exception {
        List indices = new ArrayList();
        RecordEnumeration registros = enumerateRecords(null, null, false);
        byte[] indByte;
        int intCodigo = codigo.intValue();
        int intCodigoIndice;
        int indx;
        while (registros.hasNextElement()) {
            indx = registros.nextRecordId();
            indByte = getRecord(indx);

            intCodigoIndice = Integer.valueOf(new String(indByte)).intValue();
//           System.out.println("intCodigoIndice =" + intCodigoIndice );
//           System.out.println("intCodigo ="  + intCodigo) ;
            if (intCodigo == intCodigoIndice) {
                indices.add(new Integer(indx));
            }
        }
        registros.destroy();
        registros = null;
        return indices;
    }

    //Devuelve un List con los RECORDID del Indice en un STRING
    public List getIndiceMultiple(String codigo) throws Exception {
        List indices = new ArrayList();
        RecordEnumeration registros = enumerateRecords(null, null, false);
        byte[] indByte;
        int indx;
        String valorIndice;

        while (registros.hasNextElement()) {

            indx = registros.nextRecordId();
            indByte = getRecord(indx);
            valorIndice = new String(indByte);

            if (valorIndice.equals(codigo)) {
                indices.add(new Integer(indx));
            }

        }
        registros.destroy();
        registros = null;
        return indices;
    }

    //Devuelve el RECORDID del Indice en un INTEGER dentro de un rango de indices posible
    public Integer getIndice(Integer codigo, List indices) throws Exception {

        //Enumeration enumIndices = indices.elements();

        byte[] indByte;
        Integer intCodigo;
        Integer indice = null;

        //while(enumIndices.hasMoreElements()){
        for (int i = 0; i < indices.size(); i++) {
            indice = (Integer) indices.get(i);
            indByte = getRecord(indice.intValue());
            intCodigo = Integer.valueOf(new String(indByte));
            if (codigo.longValue() <= intCodigo.longValue()) {
                break;
            }
        }

        indices.clear();
        indices = null;
        return indice;
    }

    //Devuelve los RECORDID del Indice en un INTEGER dentro de un rango de indices posible
    public List getIndiceMultiple(Integer codigo, List rango) throws Exception {
        List indices = new ArrayList();
        // Enumeration enumRango = rango.elements();

        byte[] indByte;
        int intCodigo = codigo.intValue();
        int intCodigoIndice;
        Integer indx;
        for (int i = 0; i < rango.size(); i++) {
            indx = (Integer) rango.get(i);
            indByte = getRecord(indx.intValue());
            intCodigoIndice = Integer.valueOf(new String(indByte)).intValue();
            if (intCodigo == intCodigoIndice) {
                indices.add(indx);
            }
        }
        rango.clear();
        rango = null;
        return indices;
    }

    protected Persistente createObjectBean() {
        return null;
    }

////este se agrego
      public int getIndiceBinario(String codigo) throws Exception {

        ByteArrayInputStream byteInputStream = null;

        DataInputStreamX dataInputStream = null;

        //RecordEnumeration registros = enumerateRecords(null, null, false);

        int pos=0;

        try{

            byte[] indByte;

            String strCodigo;

            int tamanio = getNumRecords();

//            System.out.println("tamanio=" + tamanio);



            int inicio = 1;

            int fin = tamanio;

            int i=0;

            boolean flag = false;


            while(inicio <= fin){

                pos = (inicio + fin) / 2;

//                System.out.println("pos="+ pos);

                indByte = getRecord(pos);
                byteInputStream = new ByteArrayInputStream(indByte);
                dataInputStream = new DataInputStreamX(byteInputStream);
                strCodigo = dataInputStream.readString();

//                System.out.println("codigoCliente == strCodigo " + codigo +"|"+strCodigo +"|");

                if ( codigo.compareTo(strCodigo) == 0) {

                    flag  = true;
                    break;

                } 
                else if (codigo.compareTo(strCodigo) > 0) { //es menor

                    inicio = pos + 1;

                } else  {
                    fin = pos - 1;

                }

                if (byteInputStream != null) {
                    byteInputStream.close();
                    byteInputStream = null;

                }

                if (dataInputStream != null) {
                    dataInputStream.close();
                    dataInputStream = null;

                }

            }



            //si no lo encuentra

             if(!flag){

                pos=0;

             }

        }finally{



            if (byteInputStream != null) {

                byteInputStream.close();

                byteInputStream = null;

            }

            if (dataInputStream != null) {

                dataInputStream.close();

                dataInputStream = null;

            }



        }

        return pos;

    }




   

}
